#include "Servidor.h"
using namespace std;

Servidor::Servidor(char* port){
	puerto=port;
	terminado=false;
	OK=true;
}


void* Servidor::run()
{
	//*----------------------*//
	//*Preparacion del socket*//
	//*----------------------*//
	cerr<<"Runnig server program on port: "<<puerto<<"..."<<endl;
	if(Bind()==-1){
		cerr<<"No se pudo Bindear al puerto: "<<puerto<<endl;
		OK=false;
		//pthread_exit(NULL);
		return(void*)1;
	}
	if(Listen()==-1){
		cerr<<"No se pudo comenzar a escuchar conexiones"<<endl;
		OK=false;
		//pthread_exit(NULL);
		return(void*)1;
	}

	//*-------------------*//
	//*Atencion a clientes*//
	//*-------------------*//
	Socket* new_sock;
	ClientManager* new_ClienteManager;
	while(!terminado){
		if((new_sock=Accept())!=NULL){
			new_ClienteManager=new ClientManager(new_sock , &L_circuitos_en_memoria, mutex_lista);
			L_ClienteManager.push_back(new_ClienteManager);
			new_ClienteManager->start();
			}
		//Los delete de los new_sock los hace cada hilo dentro suyo
	}
	cerr<<"TERMINANDO SERVIDOR"<<endl;
	//*-----------------------------*//
	//*Finalizacion de la aplicacion*//
	//*-----------------------------*//
	LiberarRecursos();
	Close();
	cerr<<"Finishing server program..."<<endl;
	//pthread_exit(NULL);
	return (void*)0;
}
	

void Servidor::LiberarRecursos(){
	//Recorro la lista de ClientManager para liberar la memoria
	list<ClientManager*>::iterator lit(L_ClienteManager.begin());
	list<ClientManager*>::iterator lend(L_ClienteManager.end());
	if(!L_ClienteManager.empty())	
		while((lit!=lend)){
			//Si el hilo aun esta en conexion con un cliente:
			if((*lit)->isBusy()){
				(*lit)->Shutdown(2);
				(*lit)->Close();
			}
			(*lit)->join();
			delete(*lit);
			++lit;
		}
}


//*------------------------*//
//*Metodos de Comunicacion *//
//*------------------------*//

int Servidor::Bind(){
	int port=atoi(puerto);
	return (socket.bind(port));
}

int Servidor::Listen(){
	return socket.listen();
}

Socket* Servidor::Accept(){
	return socket.accept();
}

int Servidor::Shutdown(int how){
	return(socket.shutdown(how));
}

int Servidor::Close(){
	return(socket.close());
}
